<!DOCTYPE html>
<html lang="en">

<head>
    <title>WebGL2</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }

        canvas {
            display: block;
        }
    </style>
</head>

<body>
    <canvas id="webgl-canvas"></canvas>
    <script type="module">
        import PARTICLE_COUNT from "./config.js";

        const canvas = document.getElementById('webgl-canvas');

        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        const gl = canvas.getContext('webgl2');

        // 调整画布大小
        function resizeCanvas() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
            gl.viewport(0, 0, canvas.width, canvas.height);
        }
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);

        // 创建粒子数据
        let particles = new Float32Array(PARTICLE_COUNT * 2); // x, y
        for (let i = 0; i < PARTICLE_COUNT * 2; i += 2) {
            particles[i] = Math.random() * 2 - 1; // x
            particles[i + 1] = Math.random() * 2 - 1; // y
        }

        // 创建缓冲区
        const buffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ARRAY_BUFFER, particles, gl.DYNAMIC_DRAW);

        // 着色器程序
        const vsSource = 
        `#version 300 es // 使用 WebGL2 的 GLSL ES 3.00 版本

        in vec2 position; // 输入顶点位置
        
        void main() {
            gl_Position = vec4(position, 1.0, 1.0); 
            gl_PointSize = 1.0; 
        }`;

        const fsSource = 
        `#version 300 es // 使用 WebGL2 的 GLSL ES 3.00 版本

        precision mediump float; // 设置浮点数精度为中等

        out vec4 fragColor; 

        void main() {
            fragColor = vec4(1.0); 
        }`;

        // 编译着色器并创建程序
        function createShader(type, source) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                console.error(gl.getShaderInfoLog(shader));
                gl.deleteShader(shader);
                return null;
            }
            return shader;
        }

        function createProgram(vsSource, fsSource) {
            const vertexShader = createShader(gl.VERTEX_SHADER, vsSource);
            const fragmentShader = createShader(gl.FRAGMENT_SHADER, fsSource);
            const program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);
            if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
                console.error(gl.getProgramInfoLog(program));
                gl.deleteProgram(program);
                return null;
            }
            return program;
        }

        const program = createProgram(vsSource, fsSource);
        gl.useProgram(program);

        // 获取属性和 uniform 位置
        const positionLoc = gl.getAttribLocation(program, 'position');
        gl.enableVertexAttribArray(positionLoc);
        gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);

        // 更新粒子逻辑
        const velocities = new Float32Array(PARTICLE_COUNT * 2);
        for (let i = 0; i < PARTICLE_COUNT * 2; i++) {
            velocities[i] = (Math.random() - 0.5) * 0.01;
        }

        function updateParticles() {
            for (let i = 0; i < PARTICLE_COUNT * 2; i += 2) {
                particles[i] += velocities[i]; // 更新 x
                particles[i + 1] += velocities[i + 1]; // 更新 y

                // 边界反弹
                if (Math.abs(particles[i]) >= 1.0) velocities[i] *= -1;
                if (Math.abs(particles[i + 1]) >= 1.0) velocities[i + 1] *= -1;
            }
            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
            gl.bufferSubData(gl.ARRAY_BUFFER, 0, particles);
        }

        // 渲染循环
        function animate() {
            updateParticles();

            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

            gl.drawArrays(gl.POINTS, 0, PARTICLE_COUNT);

            requestAnimationFrame(animate);
        }

        // 启用深度测试
        gl.enable(gl.DEPTH_TEST);
        gl.depthFunc(gl.LEQUAL);

        // 设置背景颜色
        gl.clearColor(0.0, 0.0, 0.0, 1.0);

        // 开始动画
        animate();
    </script>
</body>
</html>